//    Copyright (C) Kherty.  All rights reserved.
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Media;

namespace OpenLS.Spreadsheet.UI
{
    public class ResizeAdorner : Adorner
    {

        public ResizeAdorner(UIElement adornedElement)
            : base(adornedElement)
        {
            Resources.MergedDictionaries.Add(new ResizeAdornerResources()); 
            initialize();
        }

        private void initialize()
        {
            visualChildren = new VisualCollection(this);
            ContentControl c = new ContentControl();
            c.Template = (ControlTemplate)FindResource("resizeBorder");
            Binding b = new Binding("AdornedElement.Content");
            b.Source = this;
            c.SetBinding(DataContextProperty, b);
            visualChildren.Add(c);
            AddHandler(Thumb.DragDeltaEvent, new DragDeltaEventHandler(HandleDragDelta));

        }
        protected override Size MeasureOverride(Size constraint)
        {
            Size availableSize = new Size(AdornedElement.RenderSize.Width, AdornedElement.RenderSize.Height);
            var otherSize = availableSize;
            double d = WorksheetGrid.GetItemWidth(AdornedElement);
            if (!double.IsNaN(d))
                otherSize = new Size(d, otherSize.Height);
            d = WorksheetGrid.GetItemHeight(AdornedElement);
            if (!double.IsNaN(d))
                otherSize = new Size(otherSize.Width, d);
            availableSize = otherSize;
            int visualChildrenCount = VisualChildrenCount;
            for (int index = 0; index < visualChildrenCount; ++index)
            {
                UIElement uiElement = this.GetVisualChild(index) as UIElement;
                if (uiElement != null)
                    uiElement.Measure(otherSize);
            }
            return availableSize;
        }

        
        void HandleDragDelta(object sender, DragDeltaEventArgs args)
        {

            DependencyObject adornedElement = AdornedElement;
            Thumb hitThumb = args.OriginalSource as Thumb;
            if (adornedElement == null || hitThumb == null) return;
            args.Handled = true;
            switch (hitThumb.HorizontalAlignment)
            {
                case HorizontalAlignment.Left:
                    RaiseEvent(new DragSideDeltaEventArgs(args.HorizontalChange, args.VerticalChange, Dock.Left));break;
                case HorizontalAlignment.Right:
                    RaiseEvent(new DragSideDeltaEventArgs(args.HorizontalChange, args.VerticalChange, Dock.Right)); break;
                case HorizontalAlignment.Stretch:
                    RaiseEvent(new DragDeltaEventArgs(args.HorizontalChange, args.VerticalChange)); break;
            }
            switch (hitThumb.VerticalAlignment)
            {
                case VerticalAlignment.Top:
                    RaiseEvent(new DragSideDeltaEventArgs(args.HorizontalChange, args.VerticalChange, Dock.Top)); break;
                case VerticalAlignment.Bottom:
                    RaiseEvent(new DragSideDeltaEventArgs(args.HorizontalChange, args.VerticalChange, Dock.Bottom)); break;
            }
            this.InvalidateMeasure();   
        //    this.InvalidateMeasure();
/*

            if (adornedElement as ContentPresenter == null)
                return;
            return;
            ContentPresenter cp = (ContentPresenter)adornedElement;
            args.Handled = true;
            Anchor anchor = (Anchor)cp.Content;
            {
                switch (hitThumb.HorizontalAlignment)
                {
                    case HorizontalAlignment.Left:
                        anchor.DragSide(args.HorizontalChange, Dock.Left); break;
                    case HorizontalAlignment.Right:
                        anchor.DragSide(args.HorizontalChange, Dock.Right); break;
                    case HorizontalAlignment.Stretch:
                        anchor.Drag(args.HorizontalChange, args.VerticalChange);
                        args.Handled = true;
                        break;
                }
                switch (hitThumb.VerticalAlignment)
                {
                    case VerticalAlignment.Top:
                        anchor.DragSide(args.VerticalChange, Dock.Top); break;
                    case VerticalAlignment.Bottom:
                        anchor.DragSide(args.VerticalChange, Dock.Bottom);
                        break;
                }
            }
            UIElement parent = (UIElement)VisualTreeHelper.GetParent(adornedElement);
            parent.InvalidateMeasure();
            parent.InvalidateArrange();
            InvalidateMeasure();
            InvalidateArrange();
*/
        }

        [Category("Behavior")]
        public event DragDeltaEventHandler DragDelta
        {
            add
            {
                AddHandler(Thumb.DragDeltaEvent, value);
            }
            remove
            {
                RemoveHandler(Thumb.DragDeltaEvent, value);
            }
        }
        //public static readonly RoutedEvent DragDeltaEvent = EventManager.RegisterRoutedEvent("DragDelta", RoutingStrategy.Bubble, typeof(DragDeltaEventHandler), typeof(ResizeAdorner));

        [Category("Behavior")]
        public event DragSideDeltaEventHandler DragSideDelta
        {
            add
            {
                AddHandler(DragSideDeltaEvent, value);
            }
            remove
            {
                RemoveHandler(DragSideDeltaEvent, value);
            }
        }
        public static readonly RoutedEvent DragSideDeltaEvent = EventManager.RegisterRoutedEvent("DragSideDelta", RoutingStrategy.Bubble, typeof(DragSideDeltaEventHandler), typeof(ResizeAdorner));
        



        VisualCollection visualChildren;
        protected override Size ArrangeOverride(Size finalSize)
        {
            foreach (FrameworkElement e in visualChildren)
            {
                double x = 0, y = 0;
                Size sz = e.DesiredSize;
                switch (e.HorizontalAlignment)
                {
                    case HorizontalAlignment.Left:
                        x = -e.DesiredSize.Width; break;
                    case HorizontalAlignment.Center:
                        x = finalSize.Width / 2 - e.DesiredSize.Width / 2; break;
                    case HorizontalAlignment.Right:
                        x = finalSize.Width; break;
                }
                switch (e.VerticalAlignment)
                {
                    case VerticalAlignment.Top:
                        y = -e.DesiredSize.Height; break;
                    case VerticalAlignment.Center:
                        y = finalSize.Height / 2 - e.DesiredSize.Height / 2; break;
                    case VerticalAlignment.Bottom:
                        y = finalSize.Height; break;
                }
                if (e.HorizontalAlignment == HorizontalAlignment.Stretch && e.VerticalAlignment == VerticalAlignment.Stretch)
                {
                    sz = finalSize;
                }
                e.Arrange(new Rect(new Point(x, y), sz));
            }
            return finalSize;
        }

        protected override Visual GetVisualChild(int index)
        {
            return visualChildren[index];
        }
        protected override int VisualChildrenCount
        {
            get
            {
                if (visualChildren == null)
                    return 0;
                return visualChildren.Count;
            }
        }

    }
}
